// ============================================================================
//
// Copyright (C) 2006-2007 Dengues
//
// Google Group: http://groups.google.com/group/dengues
// QQ Group: 24885404
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ============================================================================
package org.dengues.warehouse.viewers;

import org.dengues.commons.IDenguesCoreContants;
import org.dengues.commons.IDenguesSharedImage;
import org.dengues.commons.utils.ImageUtil;
import org.dengues.core.actions.AbstractAction;
import org.dengues.core.warehouse.ENavNodeType;
import org.dengues.core.warehouse.ENodeStatus;
import org.dengues.core.warehouse.IWarehouseObject;
import org.dengues.core.warehouse.IWarehouseView;
import org.dengues.designer.ui.database.editors.DBFileEditorInput;
import org.dengues.designer.ui.process.editors.ProcessEditorInput;
import org.dengues.model.database.DatabaseDiagram;
import org.dengues.model.warehouse.ProcessType;
import org.dengues.warehouse.i18n.Messages;
import org.dengues.warehouse.models.FolderWarehouseNode;
import org.dengues.warehouse.models.WarehouseNode;
import org.dengues.warehouse.viewers.action.ClearTrashAction;
import org.dengues.warehouse.viewers.action.DeleteAction;
import org.dengues.warehouse.viewers.action.DeleteForeverAction;
import org.dengues.warehouse.viewers.action.EditPropertiesAction;
import org.dengues.warehouse.viewers.action.OpenPrefsSettingsAction;
import org.dengues.warehouse.viewers.action.RestoreAction;
import org.dengues.warehouse.viewers.database.CreateDatabaseAction;
import org.dengues.warehouse.viewers.database.CreateDbQueryAction;
import org.dengues.warehouse.viewers.database.EditDatabaseAction;
import org.dengues.warehouse.viewers.database.ReadRealDatabaseAction;
import org.dengues.warehouse.viewers.database.SynchronizeDbFromConnAction;
import org.dengues.warehouse.viewers.folder.CreateFolderAction;
import org.dengues.warehouse.viewers.process.CreateProcessAction;
import org.dengues.warehouse.viewers.process.EditProcessAction;
import org.dengues.warehouse.viewers.xml.CreateXmlFileAction;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeViewerListener;
import org.eclipse.jface.viewers.TreeExpansionEvent;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.views.properties.IPropertySheetPage;
import org.eclipse.ui.views.properties.tabbed.ITabbedPropertySheetPageContributor;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;

public class WarehouseView extends ViewPart implements IWarehouseView, ITabbedPropertySheetPageContributor {

    public static final String ID = VIEW_ID;

    private static TreeViewer viewer;

    public static WarehouseNode root = new WarehouseNode(null, null, ENavNodeType.SYSTEM_FOLDER);

    /**
     * This is a callback that will allow us to create the viewer and initialize it.
     */
    @Override
    public void createPartControl(Composite parent) {
        viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
        WarehouseViewProvider denguesViewProvider = new WarehouseViewProvider(this);
        viewer.setContentProvider(denguesViewProvider);
        viewer.setLabelProvider(denguesViewProvider);
        viewer.setSorter(new WarehouseViewNameSorter());
        IViewSite viewSite = getViewSite();
        viewer.setInput(viewSite);
        getSite().setSelectionProvider(viewer);

        makeActions();
        hookContextMenu();
        contributeToActionBars();
        WarehouseViewFactory.initDragAndDrop(viewer);
        hookDoubleClickAction();

        setPartName(Messages.getString("WarehouseView.Title.Name")); //$NON-NLS-1$
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "hookDoubleClickAction".
     */
    private void hookDoubleClickAction() {
        viewer.getTree().addMouseListener(new MouseAdapter() {

            @Override
            public void mouseDoubleClick(MouseEvent e) {
                ISelection selection = viewer.getSelection();
                if (selection instanceof IStructuredSelection) {
                    IStructuredSelection s = (IStructuredSelection) selection;
                    if (s.toArray().length == 1) {
                        WarehouseNode node2 = (WarehouseNode) s.getFirstElement();
                        ENavNodeType nodeType = node2.getNodeType();
                        if (nodeType.compareTo(ENavNodeType.SIMPLE_FOLDER) == 0
                                | nodeType.compareTo(ENavNodeType.SYSTEM_FOLDER) == 0) {
                            viewer.setExpandedState(node2, true);
                            viewer.refresh();
                            return;
                        }
                        IWarehouseObject object = node2.getObject();
                        if (object != null) {
                            Object data = object.getData();
                            IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
                            if (data instanceof DatabaseDiagram) {
                                DatabaseDiagram diagram = (DatabaseDiagram) data;
                                if (!diagram.getStatus().equals(ENodeStatus.DELETED.getId())) {
                                    DBFileEditorInput input = new DBFileEditorInput(diagram, node2.getWarehousePath());
                                    input.setWarehouseNode(node2);
                                    try {
                                        page.openEditor(input, IWarehouseView.DB_EDITOR_ID, true);
                                    } catch (PartInitException e1) {
                                        e1.printStackTrace();
                                    }
                                }
                            } else if (data instanceof ProcessType) {
                                ProcessType procesType = (ProcessType) data;
                                if (!procesType.getStatus().equals(ENodeStatus.DELETED.getId())) {
                                    ProcessEditorInput input = new ProcessEditorInput(procesType, node2.getWarehousePath());
                                    input.setWarehouseNode(node2);
                                    try {
                                        page.openEditor(input, IWarehouseView.PROC_EDITOR_ID, true);
                                    } catch (PartInitException e1) {
                                        e1.printStackTrace();
                                    }
                                }
                            }
                        }
                    }
                }
            }

        });
        viewer.addTreeListener(new ITreeViewerListener() {

            /*
             * (non-Javadoc)
             * 
             * @see org.eclipse.jface.viewers.ITreeViewerListener#treeExpanded(org.eclipse.jface.viewers.TreeExpansionEvent)
             */
            public void treeExpanded(TreeExpansionEvent event) {
                if (event.getElement() instanceof FolderWarehouseNode) {
                    viewer.setExpandedState(event.getElement(), true);
                    viewer.refresh(event.getElement(), true);
                }
            }

            /*
             * (non-Javadoc)
             * 
             * @see org.eclipse.jface.viewers.ITreeViewerListener#treeCollapsed(org.eclipse.jface.viewers.TreeExpansionEvent)
             */
            public void treeCollapsed(TreeExpansionEvent event) {
                if (event.getElement() instanceof FolderWarehouseNode) {
                    viewer.setExpandedState(event.getElement(), false);
                    viewer.refresh(event.getElement(), true);
                }
            }

        });
    }

    private AbstractAction createConn;

    private AbstractAction createProcess;

    private AbstractAction editProcess;

    private AbstractAction editDatabase;

    private AbstractAction clearBin;

    private AbstractAction delNode;

    private AbstractAction delForeverNode;

    private AbstractAction editProperties;

    private AbstractAction createDirectory;

    private AbstractAction openPrefs;

    private AbstractAction restore;

    private AbstractAction readdb;

    private AbstractAction createQuery;

    private AbstractAction creatXML;

    private AbstractAction synchronizeDb;

    /**
     * zx Comment method "makeActions".
     */
    private void makeActions() {
        refreshAction = new RefreshViewAction();
        createConn = new CreateDatabaseAction();
        createProcess = new CreateProcessAction();
        clearBin = new ClearTrashAction();
        editProcess = new EditProcessAction();
        editDatabase = new EditDatabaseAction();
        delNode = new DeleteAction();
        delForeverNode = new DeleteForeverAction();
        editProperties = new EditPropertiesAction();
        createDirectory = new CreateFolderAction();
        openPrefs = new OpenPrefsSettingsAction();
        restore = new RestoreAction();
        readdb = new ReadRealDatabaseAction();
        createQuery = new CreateDbQueryAction();
        creatXML = new CreateXmlFileAction();
        synchronizeDb = new SynchronizeDbFromConnAction();
    }

    /**
     * Passing the focus request to the viewer's control.
     */
    @Override
    public void setFocus() {
        if (!viewer.getControl().isDisposed()) {
            viewer.getControl().setFocus();
        }
    }

    private final Separator separator = new Separator(IWorkbenchActionConstants.MB_ADDITIONS);

    public void hookContextMenu() {
        MenuManager menuMgr = new MenuManager(); //$NON-NLS-1$
        menuMgr.setRemoveAllWhenShown(true);
        menuMgr.addMenuListener(new IMenuListener() {

            public void menuAboutToShow(IMenuManager manager) {
                fillContextMenu(manager);
            }

            @SuppressWarnings("unchecked")//$NON-NLS-1$
            private void fillContextMenu(IMenuManager manager) {
                createConn.setEnable();
                if (createConn.isEnabled()) {
                    manager.add(createConn);
                }

                createQuery.setEnable();
                if (createQuery.isEnabled()) {
                    manager.add(createQuery);
                }
                createProcess.setEnable();
                if (createProcess.isEnabled()) {
                    manager.add(createProcess);
                }

                createDirectory.setEnable();
                if (createDirectory.isEnabled()) {
                    manager.add(createDirectory);
                }

                clearBin.setEnable();
                if (clearBin.isEnabled()) {
                    manager.add(clearBin);
                }
                editProcess.setEnable();
                if (editProcess.isEnabled()) {
                    manager.add(editProcess);
                }
                editDatabase.setEnable();
                if (editDatabase.isEnabled()) {
                    manager.add(editDatabase);
                }

                synchronizeDb.setEnable();
                if (synchronizeDb.isEnabled()) {
                    manager.add(synchronizeDb);
                }
                creatXML.setEnable();
                if (creatXML.isEnabled()) {
                    manager.add(creatXML);
                }

                readdb.setEnable();
                if (readdb.isEnabled()) {
                    manager.add(readdb);
                }
                delForeverNode.setEnable();
                if (delForeverNode.isEnabled()) {
                    manager.add(delForeverNode);
                }

                editProperties.setEnable();
                if (editProperties.isEnabled()) {
                    manager.add(editProperties);
                }
                openPrefs.setEnable();
                if (openPrefs.isEnabled()) {
                    manager.add(openPrefs);
                }
                delNode.setEnable();
                if (delNode.isEnabled()) {
                    manager.add(delNode);
                }
                restore.setEnable();
                if (restore.isEnabled()) {
                    manager.add(restore);
                }
                manager.add(separator);
            }
        });
        Menu contextMenu = menuMgr.createContextMenu(viewer.getTree());
        viewer.getTree().setMenu(contextMenu);
    }

    public void contributeToActionBars() {
        IActionBars actionBars = getViewSite().getActionBars();
        fillLocalPullDown(actionBars.getMenuManager());
        fillLocalToolBar(actionBars.getToolBarManager());
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "fillLocalToolBar".
     * 
     * @param toolBarManager
     */
    private void fillLocalToolBar(IToolBarManager toolBarManager) {
        toolBarManager.add(refreshAction);
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "fillLocalPullDown".
     * 
     * @param menuManager
     */
    private void fillLocalPullDown(IMenuManager menuManager) {

    }

    private RefreshViewAction refreshAction;

    /**
     * Qiang.Zhang.Adolf@gmail.com WarehouseView class global comment. Detailled comment <br/>
     * 
     * $Id: Dengues.epf 1 2006-09-29 17:06:40Z qiang.zhang $
     * 
     */
    private class RefreshViewAction extends Action {

        /**
         * zx DenguesNavView.RefreshViewAction constructor comment.
         */
        public RefreshViewAction() {
            super(Messages.getString("WarehouseView.RefreshAction.Label")); //$NON-NLS-1$
            setImageDescriptor(ImageUtil.getDescriptor(IDenguesSharedImage.ACTION_REFRESH));
            setTitleToolTip(Messages.getString("WarehouseView.RefreshAction.TitleToolTip")); //$NON-NLS-1$
        }

        /*
         * (non-Javadoc)
         * 
         * @see org.eclipse.jface.action.Action#run()
         */
        @Override
        public void run() {
            root = new WarehouseNode(null, null, ENavNodeType.SYSTEM_FOLDER);
            viewer.refresh();
        }

    }

    /*
     * (non-Javadoc)
     * 
     * @see org.dengues.core.warehouse.IWarehouseView#refresh()
     */
    public void refresh(Object node) {
        root = new WarehouseNode(null, null, ENavNodeType.SYSTEM_FOLDER);
        viewer.refresh();
        viewer.setSelection(new TreeSelection());
        if (node != null) {
            if (((WarehouseNode) node).getParent() != null) {
                viewer.setExpandedState(((WarehouseNode) node).getParent(), true);
            }
        }
    }

    public void refresh() {
        root = new WarehouseNode(null, null, ENavNodeType.SYSTEM_FOLDER);
        viewer.refresh();
        viewer.setSelection(new TreeSelection());
    }

    public WarehouseNode getRoot() {
        return root;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.views.properties.tabbed.ITabbedPropertySheetPageContributor#getContributorId()
     */
    public String getContributorId() {
        return IDenguesCoreContants.ID_VIEW_PROP;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.part.WorkbenchPart#getAdapter(java.lang.Class)
     */
    @Override
    public Object getAdapter(Class adapter) {
        if (adapter == IPropertySheetPage.class) {
            return new TabbedPropertySheetPage(this);
        }
        return super.getAdapter(adapter);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.dengues.core.warehouse.IWarehouseView#expand(java.lang.Object)
     */
    public boolean isExpanded(Object node) {
        return viewer.getExpandedState(node);
    }
}
